package com.example.websocketdemo.udpUtil;

import com.example.websocketdemo.util.HttpResult;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.SpringApplication;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * TODO
 *
 * @ClassName UdpServer
 * @Author xiaojiang
 * @Date 2021/11/12 下午 14:46
 */
@RestController
@Slf4j
//@SpringBootApplication
public class UdpServer {

    private static long Come = 0;
    private final Object ComeObj = new Object();
    // FallBackUdpServer 的状态码
    private static boolean FallBackUdpServer = false;

    @RequestMapping(value = "/startFallBackUdpServer")
    public HttpResult startFallBackUdpServer(HttpServletRequest request, HttpServletResponse response) throws IOException {
        if (!FallBackUdpServer) {
            try {
                startFallBackUdpServer();
            } catch (Exception e) {
                e.printStackTrace();
                return HttpResult.newError().add("msg", "启动失败！");
            }
        }
        response.setCharacterEncoding("UTF-8");
        response.setContentType("application/json");
        return HttpResult.newSuccess().add("msg", "FallBackUdpServer 已启动！");
    }

    @RequestMapping(value = "/initializationflag")
    public HttpResult initializationflag() {
        return HttpResult.newSuccess().add("FallBackUdpServer",FallBackUdpServer).add("Count",Come);
    }

    @RequestMapping(value = "/clean")
    public HttpResult clean() {
        synchronized (ComeObj) {
            Come = 0;
            log.info("清零成功，当前接口收到了第{}次", Come);
        }
        return HttpResult.newSuccess();
    }

    private ExecutorService FallBackUdpServerThread = Executors.newFixedThreadPool(1);

    private void startFallBackUdpServer() throws Exception {
        FallBackUdpServerThread.submit(new Runnable() {
            @Override
            public void run() {
                log.info("server:connecting...");

                DatagramSocket datagramSocket = null;

                try {
                    datagramSocket = new DatagramSocket(30018);
                } catch (SocketException e1) {
                    log.error("create socket error", e1);
                    return;
                }
                FallBackUdpServer = true;
                log.info("server:connecting...");
                try {

                    while (true) {

                        byte[] buf = new byte[2048];

                        DatagramPacket datagramPacket = new DatagramPacket(buf, 0, buf.length);
                        log.info("server:waiting...");
                        datagramSocket.receive(datagramPacket);

                        handleRaMessage(datagramPacket);


                        datagramPacket = null;
                        buf = null;


                    }
                } catch (Exception e) {
                    log.info("server: Error!", e);

                }
                FallBackUdpServer = false;
                datagramSocket.close();

            }

        });


    }

    private ExecutorService raThreadPool = Executors.newFixedThreadPool(100);

    private void handleRaMessage(DatagramPacket datagramPacket) throws Exception {

        raThreadPool.submit(new Runnable() {

            @Override
            public void run() {
                String data = new String(datagramPacket.getData(), 0, datagramPacket.getLength());
                System.out.println("server:Receiving...");
                System.out.println("imsi-------" + data);
                synchronized (ComeObj) {
                    Come++;
                    log.info("当前接口收到了第{}次", Come);
                }

            }
        });
    }


    public static void main(String[] args) {

        /*try {
            startFallBackUdpServer();
        } catch (Exception e) {
            e.printStackTrace();
        }*/
        SpringApplication.run(UdpServer.class, args);

    }

}
